package org.millioncall.yueyoga.admin.service.stat;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.millioncall.openplatform.util.IDGeneratorUtils;
import org.millioncall.yueyoga.common.SystemException;

/**
 * 树结点。注：此类仅用于分组，不能通用，其获取深度的方法都是仅针对于分组的特殊性的。
 * 
 * @author zangjinyu
 * @since 1.0.0
 * @version 1.0.0
 * 
 */
public class GroupByTreeNode<T> {
	private String id;// 节点编号
	private String text;// 节点名称
	private int sort;// 节点排序
	private T data;
	private GroupByTreeNode<T> parentNode;
	private List<GroupByTreeNode<T>> childNodes;

	public GroupByTreeNode() {
		this(IDGeneratorUtils.UUID32Id());
	}

	public GroupByTreeNode(String id) {
		this.id = id;
		this.childNodes = new ArrayList<GroupByTreeNode<T>>();
	}

	public GroupByTreeNode(String id, T data) {
		this.id = id;
		this.data = data;
		this.childNodes = new ArrayList<GroupByTreeNode<T>>();
	}

	public T getData() {
		return data;
	}

	public void setData(T data) {
		this.data = data;
	}

	public String getText() {
		return text;
	}

	/**
	 * 从根节点到本节点的文本串
	 * 
	 * @return
	 */
	public String getTextChainFromRoot() {
		String chain = this.getText();
		if (this.getParentNode() != null) {// 有父节点
			chain = this.getParentNode().getTextChainFromRoot() + "," + chain;
		}
		return chain;
	}

	/**
	 * 从根节点到本节点的id串
	 * 
	 * @return
	 */
	public String getIdChainFromRoot() {
		String chain = this.getId();
		if (this.getParentNode() != null) {// 有父节点
			chain += this.getParentNode().getIdChainFromRoot() + "," + chain;
		}
		return chain;
	}

	public void setText(String text) {
		this.text = text;
	}

	public int getSort() {
		return sort;
	}

	public void setSort(int sort) {
		this.sort = sort;
	}

	public GroupByTreeNode<T> getParentNode() {
		return parentNode;
	}

	public void setParentNode(GroupByTreeNode<T> parentNode) {
		this.parentNode = parentNode;
	}

	public String getId() {
		return id;
	}

	public void addChildNode(GroupByTreeNode<T> node) {
		this.childNodes.add(node);
	}

	public void addChildNode(int index, GroupByTreeNode<T> node) {
		this.childNodes.add(index, node);
	}

	public void setChildNode(int index, GroupByTreeNode<T> node) {
		this.childNodes.set(index, node);
	}

	public void addChildNodeCollection(Collection<GroupByTreeNode<T>> nodes) {
		this.childNodes.addAll(nodes);
	}

	public void removeChildNode(GroupByTreeNode<T> node) {
		this.childNodes.remove(node);
	}

	public void removeChildNode(int index) {
		this.childNodes.remove(index);
	}

	public void clearAllChildNode() {
		this.childNodes.clear();
	}

	public List<GroupByTreeNode<T>> getChildNodes() {
		return childNodes;
	}

	/**
	 * 获取树的深度
	 * 
	 * @return
	 */
	public int getDepth() {
		if (this.childNodes.size() == 0) {
			return 1;
		} else {
			return 1 + this.childNodes.get(0).getDepth();
		}
	}

	/**
	 * 返回树节点的叶子节点的总数，如无叶子节点，则返回0。本身不计为叶子节点。
	 * 
	 * @return
	 */
	public int countOfLeafNodes() {
		int n = 0;
		if (this.childNodes.size() == 0) {
			return 0;
		} else {
			for (GroupByTreeNode<T> node : this.childNodes) {
				int n1 = node.countOfLeafNodes();
				n += n1 == 0 ? 1 : n1;
			}
		}
		return n;
	}

	/**
	 * 返回树的总结点数，包含自身
	 * 
	 * @return
	 */
	public int countOfTotalNodes() {
		int n = 1;
		for (GroupByTreeNode<T> node : this.childNodes) {
			n += node.countOfTotalNodes();
		}
		return n;
	}

	/**
	 * 获得第几层的所有节点，第一层深度即自身
	 * 
	 * @param depth
	 * @return
	 */
	public List<GroupByTreeNode<T>> getTreeNodesOfDepth(int depth) {
		if (depth < 1) {
			throw new SystemException("树的深度最少为1");
		}
		List<GroupByTreeNode<T>> rtn = new ArrayList<GroupByTreeNode<T>>();
		if (depth == 1) {
			rtn.add(this);
		} else {
			List<GroupByTreeNode<T>> prev = getTreeNodesOfDepth(depth - 1);
			for (GroupByTreeNode<T> node : prev) {
				rtn.addAll(node.getChildNodes());
			}
		}
		return rtn;
	}

}
